package xgb
import(
	"errors"
	"os"
	"os/exec"
	"regexp"
	"strconv"
)

/*
.vars:
*/
var BytesShort=errors.New("[]byte is too short")






/*
.func :
*/



/*
.func getAuthKey:
*/
// 返回MIT-MAGIC-COOKIE-1验证方法的KEY，KEY将作为首次连接X Server时发送的数据中的authorization-protocol-data字段，而authorization-protocol-name字段应为验证方法名：MIT-MAGIC-COOKIE-1
func getAuthKey()[]byte{
	host,err:=os.Hostname(); if err!=nil{panic("Can't Get Hostname!")}
	authEntrys,err:=exec.Command("xauth", "list").Output(); if err!=nil{ panic(err) }
	reg,err:=regexp.Compile(`(?:^|\n)`+host+`/unix:[0-9]+ +MIT-MAGIC-COOKIE-1 +([0-9a-fA-F]+)\n`); if err!=nil{	panic(err) }

	var strKey string
	if reg.Match(authEntrys){
		strKey=string(reg.FindSubmatch(authEntrys)[1])
	}else{panic("Can't Get AuthKey!")}

	var numKey = []byte{}
	for i:=0;i<len(strKey)-1;i+=2{
		val,err:=strconv.ParseUint(strKey[i:i+2],16,8); if err!=nil{ panic(err) }
		numKey=append(numKey,byte(val))
	}//for
	return numKey
}//getAuthKey






/*
.func CountMaskBits:
*/
func CountMaskBits(msk uint32)(ret uint16){
	for i:=0;i<31;i++{
		if msk&1==1{ret++}
		msk>>=1
	}
	return
}//CountMaskBits




/*
.func IntToBytes:
*/
func Int16ToBytes(i16 int16)[]byte{
	u16:=uint16(i16)
	return []byte{byte(u16>>8), byte(u16&0xff)}
}


func Int32ToBytes(i32 int32)[]byte{
	u32:=uint32(i32)
	return []byte{byte(u32>>24), byte((u32>>16)&0xff), byte((u32>>8)&0xff), byte(u32&0xff)}
}


func Int64ToBytes(i64 int64)[]byte{
	u64:=uint64(i64)
	return []byte{byte(u64>>56), byte((u64>>48)&0xff), byte((u64>>40)&0xff), byte((u64>>32)&0xff), byte((u64>>24)&0xff), byte((u64>>16)&0xff), byte((u64>>8)&0xff), byte(u64&0xff)}
}


func Uint16ToBytes(u16 uint16)[]byte{
	return []byte{byte(u16>>8), byte(u16&0xff)}
}


func Uint32ToBytes(u32 uint32)[]byte{
	return []byte{byte(u32>>24), byte((u32>>16)&0xff), byte((u32>>8)&0xff), byte(u32&0xff)}
}


func Uint64ToBytes(u64 uint64)[]byte{
	return []byte{byte(u64>>56), byte((u64>>48)&0xff), byte((u64>>40)&0xff), byte((u64>>32)&0xff), byte((u64>>24)&0xff), byte((u64>>16)&0xff), byte((u64>>8)&0xff), byte(u64&0xff)}
}



/*
.func BytesToInt:
*/
func BytesToInt16(b16 []byte)int16{
	if len(b16)<2{panic(BytesShort)}
	return int16((uint16(b16[0])<<8)|uint16(b16[1]))
}


func BytesToInt32(b32 []byte)int32{
	if len(b32)<4{panic(BytesShort)}
	return int32((uint32(b32[0])<<24)|(uint32(b32[1])<<16)|(uint32(b32[2])<<8)|uint32(b32[3]))
}


func BytesToInt64(b64 []byte)int64{
	if len(b64)<8{panic(BytesShort)}
	return int64((uint64(b64[0])<<56)|(uint64(b64[1])<<48)|(uint64(b64[2])<<40)|(uint64(b64[3])<<32)|(uint64(b64[4])<<24)|(uint64(b64[5])<<16)|(uint64(b64[6])<<8)|uint64(b64[7]))
}



func BytesToUint16(b16 []byte)uint16{
	if len(b16)<2{panic(BytesShort)}
	return (uint16(b16[0])<<8)|uint16(b16[1])
}


func BytesToUint32(b32 []byte)uint32{
	if len(b32)<4{panic(BytesShort)}
	return (uint32(b32[0])<<24)|(uint32(b32[1])<<16)|(uint32(b32[2])<<8)|uint32(b32[3])
}


func BytesToUint64(b64 []byte)uint64{
	if len(b64)<8{panic(BytesShort)}
	return (uint64(b64[0])<<56)|(uint64(b64[1])<<48)|(uint64(b64[2])<<40)|(uint64(b64[3])<<32)|(uint64(b64[4])<<24)|(uint64(b64[5])<<16)|(uint64(b64[6])<<8)|uint64(b64[7])
}